﻿using System;
using System.Runtime.InteropServices;
using StockUtil;

namespace StockLib.Data
{
    // 财务信息数据结构 CStock::dataBasetbl
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct CodeFilePack
    {
        // 代码数据
        public UInt16 m_wMarket;                                // 股票市场类型
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)]
        public string m_szLabel;                                // 代码
        public UInt16 m_wType;                                  // 类型
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string m_szName;                                 // 名称
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
        public string m_szShortName;                            // 简称

        // 行情数据
        public Int32 m_time;                                    // 交易时间
        public Single m_fLastClose;                             // 昨收
        public Single m_fOpen;                                  // 今开
        public Single m_fHigh;                                  // 最高
        public Single m_fLow;                                   // 最低
        public Single m_fNewPrice;                              // 最新
        public Single m_fVolume;                                // 成交量
        public Single m_fAmount;                                // 成交额
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
        public Single[] m_fBuyPrice;                            // 申买价1,2,3
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
        public Single[] m_fBuyVolume;                           // 申买量1,2,3
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
        public Single[] m_fSellPrice;                           // 申卖价1,2,3
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
        public Single[] m_fSellVolume;                          // 申卖量1,2,3

        // 财务数据
        public Int32 m_reportDate;              // 报告更新时间
        public Int32 m_reportType;              // 报告类型：年报、中报、季报
        public Single m_fErateDollar;			// 当期美元汇率
        public Single m_fErateHkDollar;		    // 当期港币汇率
        // ★偿债能力
        public Single m_fRatioLiquidity;		// 流动比率
        public Single m_fRatioQuick;			// 速动比率
        public Single m_fVelocityReceivables;	// 应收帐款周率
        // ★经营能力
        public Single m_fVelocityMerchandise;	// 存货周转率
        public Single m_fMainIncome;			// 主营业务收入
        public Single m_fCashPs;				// 每股净现金流量
        // ★盈利能力
        public Single m_fProfitMargin;			// 主营业务利润率 %
        public Single m_fNetAssetYield;		// 净资产收益率 %
        // ★资本结构
        public Int32 m_dateBegin;				// 上市日期 Format is YYYYMMDD
        public Single m_fShareCountTotal;		// 总股本
        public Single m_fShareCountA;			// 流通A股
        public Single m_fShareCountB;			// 流通B股
        public Single m_fShareCountH;			// 流通H股
        public Single m_fShareCountNational;	// 国有股
        public Single m_fShareCountCorp;		// 法人股
        public Single m_fProfitPsud;			// 每股未分配利润
        public Single m_fAsset;					// 总资产
        public Single m_fRatioHolderRight;		// 股东权益比率
        public Single m_fRatioLongDebt;		    // 长期负债率
        public Single m_fRatioDebt;			    // 资产负债率
        // ★投资收益能力
        public Single m_fNetAssetPs;			// 每股净资产
        public Single m_fNetAssetPsRegulate;	// 调整每股净资产
        public Single m_fEps;					// 每股收益
        public Single m_fEpsDeduct;			    // 扣除后每股收益
        public Single m_fNetProfit;			    // 净利润
        public Single m_fMainProfit;			// 主营业务利润
        public Single m_fTotalProfit;			// 利润总额
        // ★增长率
        public Single m_fProfitInc;			    // 主营利润增长率%
        public Single m_fIncomeInc;			    // 主营收入增长率%
        public Single m_fAssetInc;				// 总资产增长率%
        // ★技术数据统计值
        public Single m_fYieldAverage;			// 平均收益率%
        public Single m_fYieldStddev;			// 收益标准差%
        public Single m_fBeite;					// β值

        public static CodeFilePack FromInternal(Stock stock)
        {
            CodeFilePack codePack = new CodeFilePack();
            codePack.m_wMarket = (UInt16)stock.Market;
            codePack.m_szLabel = stock.Code;
            codePack.m_wType = (UInt16)stock.Type;
            codePack.m_szName = stock.Name;
            codePack.m_szShortName = stock.ShortName;

            codePack.m_time = stock.Time;
            codePack.m_fLastClose = stock.Close;
            codePack.m_fOpen = stock.Open;
            codePack.m_fHigh = stock.High;
            codePack.m_fLow = stock.Low;
            codePack.m_fNewPrice = stock.New;
            codePack.m_fVolume = stock.Volume;
            codePack.m_fAmount = stock.Amount;
            codePack.m_fBuyPrice = new float[5];
            codePack.m_fBuyPrice[0] = stock.BuyPrice[0];
            codePack.m_fBuyPrice[1] = stock.BuyPrice[1];
            codePack.m_fBuyPrice[2] = stock.BuyPrice[2];
            codePack.m_fBuyPrice[3] = stock.BuyPrice[3];
            codePack.m_fBuyPrice[4] = stock.BuyPrice[4];
            codePack.m_fBuyVolume = new float[5];
            codePack.m_fBuyVolume[0] = stock.BuyVolume[0];
            codePack.m_fBuyVolume[1] = stock.BuyVolume[1];
            codePack.m_fBuyVolume[2] = stock.BuyVolume[2];
            codePack.m_fBuyVolume[3] = stock.BuyVolume[3];
            codePack.m_fBuyVolume[4] = stock.BuyVolume[4];
            codePack.m_fSellPrice = new float[5];
            codePack.m_fSellPrice[0] = stock.SellPrice[0];
            codePack.m_fSellPrice[1] = stock.SellPrice[1];
            codePack.m_fSellPrice[2] = stock.SellPrice[2];
            codePack.m_fSellPrice[3] = stock.SellPrice[3];
            codePack.m_fSellPrice[4] = stock.SellPrice[4];
            codePack.m_fSellVolume = new float[5];
            codePack.m_fSellVolume[0] = stock.SellVolume[0];
            codePack.m_fSellVolume[1] = stock.SellVolume[1];
            codePack.m_fSellVolume[2] = stock.SellVolume[2];
            codePack.m_fSellVolume[3] = stock.SellVolume[3];
            codePack.m_fSellVolume[4] = stock.SellVolume[4];

            codePack.m_reportDate = stock.ReportDate;
            codePack.m_reportType = (int) stock.ReportType;
            codePack.m_fErateDollar = stock.ErateDollar;
            codePack.m_fErateHkDollar = stock.ErateHkDollar;
            codePack.m_fRatioLiquidity = stock.RatioLiquidity;
            codePack.m_fRatioQuick = stock.RatioQuick;
            codePack.m_fVelocityReceivables = stock.VelocityReceivables;
            codePack.m_fVelocityMerchandise = stock.VelocityMerchandise;
            codePack.m_fMainIncome = stock.MainIncome;
            codePack.m_fCashPs = stock.CashPs;
            codePack.m_fProfitMargin = stock.ProfitMargin;
            codePack.m_fNetAssetYield = stock.NetAssetYield;
            codePack.m_dateBegin = stock.DateBegin;
            codePack.m_fShareCountTotal = stock.ShareCountTotal;
            codePack.m_fShareCountA = stock.ShareCountA;
            codePack.m_fShareCountB = stock.ShareCountB;
            codePack.m_fShareCountH = stock.ShareCountH;
            codePack.m_fShareCountNational = stock.ShareCountNational;
            codePack.m_fShareCountCorp = stock.ShareCountCorp;
            codePack.m_fProfitPsud = stock.ProfitPsud;
            codePack.m_fAsset = stock.Asset;
            codePack.m_fRatioHolderRight = stock.RatioHolderRight;
            codePack.m_fRatioLongDebt = stock.RatioLongDebt;
            codePack.m_fRatioDebt = stock.RatioDebt;
            codePack.m_fNetAssetPs = stock.NetAssetPs;
            codePack.m_fNetAssetPsRegulate = stock.NetAssetPsRegulate;
            codePack.m_fEps = stock.Eps;
            codePack.m_fEpsDeduct = stock.EpsDeduct;
            codePack.m_fNetProfit = stock.NetProfit;
            codePack.m_fMainProfit = stock.MainProfit;
            codePack.m_fTotalProfit = stock.TotalProfit;
            codePack.m_fProfitInc = stock.ProfitInc;
            codePack.m_fIncomeInc = stock.IncomeInc;
            codePack.m_fAssetInc = stock.AssetInc;
            codePack.m_fYieldAverage = stock.YieldAverage;
            codePack.m_fYieldStddev = stock.YieldStddev;
            codePack.m_fBeite = stock.Beite;

            return codePack;
        }

        public static Stock ToInternal(ref CodeFilePack codePack)
        {
            Stock stock = new Stock();
            stock.Market = (StockMarket)codePack.m_wMarket;
            stock.Code = codePack.m_szLabel;
            stock.Name = codePack.m_szName;
            stock.Type = StockHelper.GetStockType(stock);
            stock.ShortName = StringHelper.GetPinYin(stock.Name);

            ReportData reportData = new ReportData();
            reportData.Time = codePack.m_time;
            reportData.Close = codePack.m_fLastClose;
            reportData.Open = codePack.m_fOpen;
            reportData.High = codePack.m_fHigh;
            reportData.Low = codePack.m_fLow;
            reportData.New = codePack.m_fNewPrice;
            reportData.Volume = codePack.m_fVolume;
            reportData.Amount = codePack.m_fAmount;
            reportData.BuyPrice[0] = codePack.m_fBuyPrice[0];
            reportData.BuyPrice[1] = codePack.m_fBuyPrice[1];
            reportData.BuyPrice[2] = codePack.m_fBuyPrice[2];
            reportData.BuyPrice[3] = codePack.m_fBuyPrice[3];
            reportData.BuyPrice[4] = codePack.m_fBuyPrice[4];
            reportData.BuyVolume[0] = codePack.m_fBuyVolume[0];
            reportData.BuyVolume[1] = codePack.m_fBuyVolume[1];
            reportData.BuyVolume[2] = codePack.m_fBuyVolume[2];
            reportData.BuyVolume[3] = codePack.m_fBuyVolume[3];
            reportData.BuyVolume[4] = codePack.m_fBuyVolume[4];
            reportData.SellPrice[0] = codePack.m_fSellPrice[0];
            reportData.SellPrice[1] = codePack.m_fSellPrice[1];
            reportData.SellPrice[2] = codePack.m_fSellPrice[2];
            reportData.SellPrice[3] = codePack.m_fSellPrice[3];
            reportData.SellPrice[4] = codePack.m_fSellPrice[4];
            reportData.SellVolume[0] = codePack.m_fSellVolume[0];
            reportData.SellVolume[1] = codePack.m_fSellVolume[1];
            reportData.SellVolume[2] = codePack.m_fSellVolume[2];
            reportData.SellVolume[3] = codePack.m_fSellVolume[3];
            reportData.SellVolume[4] = codePack.m_fSellVolume[4];
            stock.Report = reportData;

            FinanceData financeData = new FinanceData();
            financeData.ReportDate = codePack.m_reportDate;
            financeData.ReportType = codePack.m_reportType;
            financeData.ErateDollar = codePack.m_fErateDollar;
            financeData.ErateHkDollar = codePack.m_fErateHkDollar;
            financeData.RatioLiquidity = codePack.m_fRatioLiquidity;
            financeData.RatioQuick = codePack.m_fRatioQuick;
            financeData.VelocityReceivables = codePack.m_fVelocityReceivables;
            financeData.VelocityMerchandise = codePack.m_fVelocityMerchandise;
            financeData.MainIncome = codePack.m_fMainIncome;
            financeData.CashPs = codePack.m_fCashPs;
            financeData.ProfitMargin = codePack.m_fProfitMargin;
            financeData.NetAssetYield = codePack.m_fNetAssetYield;
            financeData.DateBegin = codePack.m_dateBegin;
            financeData.ShareCountTotal = codePack.m_fShareCountTotal;
            financeData.ShareCountA = codePack.m_fShareCountA;
            financeData.ShareCountB = codePack.m_fShareCountB;
            financeData.ShareCountH = codePack.m_fShareCountH;
            financeData.ShareCountNational = codePack.m_fShareCountNational;
            financeData.ShareCountCorp = codePack.m_fShareCountCorp;
            financeData.ProfitPsud = codePack.m_fProfitPsud;
            financeData.Asset = codePack.m_fAsset;
            financeData.RatioHolderRight = codePack.m_fRatioHolderRight;
            financeData.RatioLongDebt = codePack.m_fRatioLongDebt;
            financeData.RatioDebt = codePack.m_fRatioDebt;
            financeData.NetAssetPs = codePack.m_fNetAssetPs;
            financeData.NetAssetPsRegulate = codePack.m_fNetAssetPsRegulate;
            financeData.Eps = codePack.m_fEps;
            financeData.EpsDeduct = codePack.m_fEpsDeduct;
            financeData.NetProfit = codePack.m_fNetProfit;
            financeData.MainProfit = codePack.m_fMainProfit;
            financeData.TotalProfit = codePack.m_fTotalProfit;
            financeData.ProfitInc = codePack.m_fProfitInc;
            financeData.IncomeInc = codePack.m_fIncomeInc;
            financeData.AssetInc = codePack.m_fAssetInc;
            financeData.YieldAverage = codePack.m_fYieldAverage;
            financeData.YieldStddev = codePack.m_fYieldStddev;
            financeData.Beite = codePack.m_fBeite;
            stock.Finance = financeData;

            return stock;
        }
    };
}
